package subpages;

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTextField;

import model.Library;
import model.QA;

/**
 * This sub page contains the library elements allowing the user to search and
 * copy responses.
 * 
 * @author Robert Ogden rogden33
 */
public class LibraryPage extends JPanel {

	/**
	 * A reference to the library
	 */
	private final Library myLibrary;

	/**
	 * A reference to the top search bar to get text from
	 */
	private final JTextField mySearchBar;

	/**
	 * Based on the selection of radio button, which field to search in.
	 */
	private SearchOn myQueryType;

	/**
	 * The list of responses to dislay in the center panel.
	 */
	private List<QA> myDisplay;

	/**
	 * Creates a new library page with an empty listing in the middle to start
	 * with.
	 * 
	 * @param library
	 *            the model library reference to search through
	 */
	public LibraryPage(final Library library) {
		super(new BorderLayout());
		myLibrary = library;
		myDisplay = new ArrayList<QA>();
		mySearchBar = new JTextField("Enter search string here");
		myQueryType = SearchOn.All;
		addContent();
		// search when enter is pressed
		mySearchBar.addKeyListener(new KeyAdapter() {
			public void keyPressed(final KeyEvent e) {
				if (e.getKeyCode() == KeyEvent.VK_ENTER) {
					new SearchActionListener().actionPerformed(null);
				}
			}
		});
		// when the search bar is clicked on, clear it
		mySearchBar.addMouseListener(new MouseAdapter() {
			public void mouseClicked(final MouseEvent e) {
				mySearchBar.setText("");
			}
		});
	}

	/**
	 * Adds the content to the panel.
	 */
	private void addContent() {
		// top panel with search bar and selection buttons
		final JPanel topPanel = new JPanel(new GridLayout(1, 2));
		final JPanel searchBarPanel = new JPanel(new BorderLayout());
		searchBarPanel.add(mySearchBar, BorderLayout.CENTER);
		final JButton searchButton = new JButton("Search");
		searchButton.addActionListener(new SearchActionListener());
		searchBarPanel.add(searchButton, BorderLayout.EAST);
		final JPanel selectionPanel = new JPanel();
		selectionPanel.add(new JLabel("Search By: "));
		topPanel.add(searchBarPanel);
		topPanel.add(selectionPanel);
		final ButtonGroup group = new ButtonGroup();
		// build the buttons off of the SearchOn enum below
		for (SearchOn query : SearchOn.values()) {
			final JRadioButton button = new JRadioButton(query.toString());
			button.addActionListener(new ActionListener() {
				public void actionPerformed(final ActionEvent e) {
					myQueryType = query;
				}
			});
			if (query == myQueryType) {
				button.setSelected(true);
			}
			group.add(button);
			selectionPanel.add(button);
		}
		// the center list panel
		final LibraryListPanel listPanel = new LibraryListPanel(myDisplay);
		final JScrollPane scroll = new JScrollPane(
				JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
				JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
		scroll.setViewportView(listPanel);
		add(topPanel, BorderLayout.NORTH);
		add(scroll, BorderLayout.CENTER);
	}

	/**
	 * When the search button is clicked, or the user presses enter on the
	 * search bar, search the library and display the results of the search.
	 * 
	 * @author Robert
	 *
	 */
	private class SearchActionListener implements ActionListener {

		/**
		 * Based on the current button selection, run a search and then repaint.
		 */
		public void actionPerformed(final ActionEvent e) {
			final String text = mySearchBar.getText();
			switch (myQueryType) {
			case All:
				final Set<QA> set = new HashSet<QA>();
				set.addAll(myLibrary.browseByCategory(text));
				set.addAll(myLibrary.searchByQuestion(text));
				set.addAll(myLibrary.searchByAnswer(text));
				set.addAll(myLibrary.searchByKeyword(text));
				myDisplay = new ArrayList<QA>(set);
				break;
			case Category:
				myDisplay = myLibrary.browseByCategory(text);
				break;
			case Question:
				myDisplay = myLibrary.searchByQuestion(text);
				break;
			case Answer:
				myDisplay = myLibrary.searchByAnswer(text);
				break;
			case Keyword:
				myDisplay = myLibrary.searchByKeyword(text);
				break;
			}
			removeAll();
			addContent();
			revalidate();
			repaint();
		}
	}

	/**
	 * The different types of searches that can be done.
	 * 
	 * @author Robert
	 *
	 */
	private enum SearchOn {

		All,

		Category,

		Question,

		Answer,

		Keyword;

	}
}
